iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 22
2
Modern Web

美麗的邂逅-與安室....伊春系列 第 22

競合一: 後端 (Link/Spring Boot)

  • 分享至 

  • xImage
  •  
如果我們生命夠成熟,心胸夠開擴,會發現,往往完美的競爭就是完美的合作。
  • @Entity, @GeneratedValue, @Repository, @RequestBody
  • CommandLineRunner
  • H2Database

接著我們要把前端Angular和後端Spring Boot連在一起,在這裡,區分為三回:

  1. Backend (Spring Boot)
  2. Frontend (Angular)
  3. Communication (HTTP)

這樣我的壓力小一些,當然,這裡只是蜻蜓點水,孫悟空到此一遊,其中的變化,還要進一步花費時間。另外,這前後端程式通常會在同一部電腦上執行,因此前端程式Angular就不能放在 StartBlitz 網站,這是有安全性考量的。
現在,我們要把 Angular (front-end) and Spring Boot (back-end) 強強整合。Spring也提供 Spring MVC,因此,也可以不要 Angular,用 Spring / Spring MVC 來完成,就好像可以買一部轎貨車,又當轎車,又當貨車,也可以買兩台車,一台是轎車,一台是貨車,各隨主便,和有千秋。而我是喜歡豐富的,因此Angular, Spring boot 都想了解。這兩者各別的介紹,在前面章回均已經加以說明,在這一回中,我們專注如何連結。這個範例是以這個網頁-Baeldung為藍本,在此特別聲明並感謝,讀者有興趣也可以對照比較。
先展示結果:
https://ithelp.ithome.com.tw/upload/images/20191007/20120951lVRo9zklk3.png
這是一個典型的CRUD應用,但這一回只是為了介紹 Angular 與 Spring boot 的連結,因此其他部分就簡化,只介紹Retrieve (列出所有的資料),Create (創建資料),資料只有名稱(name)及郵編位址(email)。整個程式有兩個部分,一個是Angular, 一個是Spring boot, 為避免太長,我們區分為兩回來介紹。在這一回中介紹 Spring , 下一回中介紹 Angular。在此先使用者 (User) 的類別,這是記錄的結構:

src/main/java/User.java
@Entity
public class User {
    public User() {
	  super();
	  this.name="unknown";
	  this.email="unknown.email";
}
public User(String name, String email) {
	  super();
	  this.name = name;
	  this.email = email;
}
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private final String name;
private final String email;
public long getId()      { return id; }
public void setId(long id) { this.id = id; }
public String getName()  {return name;}
public String getEmail()  {return email;}
}

@Entity, @GeneratedValue 是 H2Database 的 annotation, 必須增加相依關係於 pom.xml

<dependency>
    	<groupId>com.h2database</groupId>
    	<artifactId>h2</artifactId>
    	<scope>runtime</scope>
</dependency>

H2Database 是一個 in-memory 的資料庫管理系統。@Entity表示是資料(@Repository)中的記錄結構。@Id, @GeneratedValue 讓 @Id 這個欄位逐筆加1. Spring Data JDBC 需要有 id 才能運作,不過上頭的 @Id 並不是 class user中的 Id,而是 org.springframework.data.annotation.Id。
src/main/java/UserREpository.java

@Repository
public interface UserRepository extends CrudRepository<User, Long>{}

創建資料庫只用了一行程式。界面(interface) CrudRepository 定義了所有我們要的功能, 如save()、findById()、delete()、deleteById()、count()等函數。@Repository 是 @Command 的衍生 “符" (annotation),因此,程式中,我們沒有看見 new UserRepository, 而是在UserController 中被注入(injection)。第一個參數User 是Entity的型別,而第二個參數 long 是主鍵 (primary key) 的型別。特別強調,我們所編碼的 UserRepository 是界面(interface),而不是類別(class),這是為什麼我們可以省事的原因。(界面裡沒有實作的邏輯,這些框架處理掉了)。

src/java/UserController.java
@RestController
@CrossOrigin(origins = "http://localhost:4200")
public class UserController {
 
	public UserController(UserRepository userRepository) {
		super();
		this.userRepository = userRepository;
	}
    
    private final UserRepository userRepository;
 
    @GetMapping("/users")
    public List<User> getUsers() {
        return (List<User>) userRepository.findAll();
    }
 
    @PostMapping("/users")
    void addUser(@RequestBody User user) {
        userRepository.save(user);
    }
}

在@CrossOrigin 定義只有 localhost 才可以讀取資料,這是要避免沒有授權的讀取資料。

src/main/java/AngularDemoApplication.java
@SpringBootApplication
public class AngularDemoApplication {
	public static void main(String[] args) {
		SpringApplication.run(AngularDemoApplication.class, args);
	}
    @Bean
    CommandLineRunner init(UserRepository userRepository) {
        return args -> {
            Stream.of("Mattrew", "Mark", "Luke", "John", "Lucifer", "Satan").forEach(name -> {
                User user = new User(name, name.toLowerCase() + "@domain.com");
                userRepository.save(user);
            });
            userRepository.findAll().forEach(System.out::println);
        };
    }
}

程式啟動時,會自動執行 CommandLineRunner 所定義的函式。也可以定義繼承 CommandLineRunner 的衍生類別,衍生類別中的 run() 函式,會在啟動時執行。在上例這個起啟函式中,將產生測試的資料。

@Component
publc class MyStartup implements CommandLineRunner{
    @Override
    Public void run(String… args) throws Exception { … }
    …

可以有一個以上的類別繼承 CommandLineRunner,但是 @Bean CommandLineRunner 函式只能有一個。


上一篇
過路劫財 (AOC)
下一篇
競合二: 前端 (Link/Angular)
系列文
美麗的邂逅-與安室....伊春30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言